﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.MessageBus;
using NGinnBPM.Runtime.Messages;
using NGinnBPM.Runtime.Events;
using NLog;
using System.Diagnostics;
using System.IO;
using NGinnBPM.Lib.Exceptions;

namespace NGinnBPM.Services.Email
{
    /// <summary>
    /// Default email sender. Sends email using the BLAT utility
    /// </summary>
    public class DefaultEmailSender : IMessageConsumer<SendEmailMessage>, IEmailSender
    {
        protected Logger log = LogManager.GetCurrentClassLogger();

        public IServiceResolver ServiceLocator { get; set; }
        public IMessageBus MessageBus { get; set; }
        
        #region IMessageConsumer<SendEmailMessage> Members

        public void Handle(SendEmailMessage message)
        {
            try
            {
                Send(message);
                MessageBus.Reply(new TaskInstanceSuccess(message.CorrelationId, message.CorrelationId));
            }
            catch (NGinnException nex)
            {
                log.Warn("Error sending email: {0}", nex);
                MessageBus.Reply(new TaskInstanceFailure(message.CorrelationId, nex.Message));
            }
            
        }

        #endregion

       
        /// <summary>
        /// Temporary directory
        /// </summary>
        public string TempDir { get; set; }
        
        /// <summary>
        /// Blat exe path
        /// </summary>
        public string ExePath { get; set; }
        
        /// <summary>
        /// Blat commandline
        /// </summary>
        public string CmdLine { get; set; }
        

        public virtual void Send(SendEmailMessage msg)
        {
            lock (this)
            {
                if (!Directory.Exists(TempDir)) Directory.CreateDirectory(TempDir);
            }
            string fn = Guid.NewGuid().ToString("N") + ".txt";
            string bodyFile = Path.Combine(TempDir, fn);
            using (StreamWriter sw = new StreamWriter(bodyFile, false, Encoding.UTF8))
            {
                sw.Write(msg.BodyText);
            }
            string arguments = string.Format("\"{0}\" -to \"{1}\" -subject \"{2}\" {3}", bodyFile, msg.Recipients[0], msg.Subject, CmdLine);
            log.Info("Blat commandline: {0} {1}", ExePath, arguments);
            int ret;
            ProcessStartInfo psi = new ProcessStartInfo(ExePath, arguments);
            using (Process p = Process.Start(psi))
            {
                p.WaitForExit();
                log.Info("Email sent");
                ret = p.ExitCode;
            }
            if (ret != 0)
            {
                log.Warn("Failed to send email: {0}. {1}", ret, arguments);
                throw new NGinnException("Failed to send email - blat returned an error");
            }
        }

        
    }
}